#include <iostream>
#include <stdexcept>
#include "../include/file_encryptor_decryptor.hpp"

namespace alexcr4ckpentest
{
  void FileEncryptorDecryptor::set_target_file(const std::string& target_filename)
  {
    m_target_file_name = target_filename;
  }

  void FileEncryptorDecryptor::process_data(uint64_t base_key, uint32_t salt_key, mode_t mode)
  {
    m_file_stream.open(m_target_file_name);

    if (!m_file_stream.is_open())
    {
      throw std::runtime_error{"Could not open file: " + m_target_file_name};
    }

    std::string file_data{std::istreambuf_iterator<char>{m_file_stream}, std::istreambuf_iterator<char>{}};

    const auto encrypt{[](uint64_t base_key, uint32_t salt_key, std::string& file_data)
    {
      for (char& chr : file_data)
      {
        chr ^= base_key;
        chr ^= salt_key;
      }
    }};

    const auto decrypt{[](uint64_t base_key, uint32_t salt_key, std::string& file_data)
    {
      for (char& chr : file_data)
      {
        chr ^= salt_key;
        chr ^= base_key;
      }
    }};

    if (mode == mode_t::encrypt)
    {
      encrypt(base_key, salt_key, file_data);
    }
    else if (mode == mode_t::dectrypt)
    {
      decrypt(base_key, salt_key, file_data);
    }

    m_file_stream.seekp(0);
    m_file_stream << file_data;
    m_file_stream.close();
  }
} // namespace alex
